﻿using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;

namespace OpenPowerPoint
{
    /// <summary>
    /// Resolves Bindings between Ids and rIds
    /// </summary>
    /// <remarks>
    /// In OpenXML, there are two types of Ids:
    /// <list type="bullet">
    /// <item>Numbered Ids</item>
    /// <item>Relative Ids</item>
    /// </list>
    /// rIds are the more common ones, but Ids are also used.
    /// </remarks>
    internal static class RelationResolver
    {
        /// <summary>
        /// An internal counter for the current relation
        /// </summary>
        private static int _relations;
        /// <summary>
        /// An internal counter for the current slide Id
        /// </summary>
        private static uint _slides = 255;

        #region Relation Management
        /// <summary>
        /// Starts a new relation stack for saving
        /// </summary>
        /// <remarks>This function simply resets <see cref="_relations"/> and <see cref="_slides"/> to their initial values.</remarks>
        public static void StartRelationStack()
        {
            _slides = 255;
            _relations = 0;
        }

        /// <summary>
        /// Returns an unused Relation Id
        /// </summary>
        /// <returns>The next free rId</returns>
        public static string GetNextRelationId()
        {
            _relations++;

            return "rId" + _relations;
        }

        /// <summary>
        /// Returns an unused Slide Id
        /// </summary>
        /// <returns>returns the next slide Id</returns>
        public static uint GetNextSlideId()
        {
            _slides++;

            return _slides;
        }

        
        #endregion

        #region Slides
        /// <summary>
        /// Returns a SlidePart according to the submitted Id
        /// </summary>
        /// <param name="id">The numeric Id of the desired slide</param>
        /// <param name="presentation">The PresentationPart which contains the slide</param>
        /// <returns>A SlidePart with the resolved Id</returns>
        public static SlidePart GetSlideById(uint id, PresentationPart presentation)
        {
            string rid = null;

            foreach (SlideId slideId in presentation.Presentation.SlideIdList)
            {
                if (slideId.Id == id)
                {
                    rid = slideId.RelationshipId;
                    break;
                }
            }

            if (rid == null) return null;

            return (SlidePart)presentation.GetPartById(rid);
        }

        /// <summary>
        /// Returns a SlideMasterPart according to the submitted Id
        /// </summary>
        /// <param name="id">The numeric Id of the desired slide master</param>
        /// <param name="presentation">The PresentationPart which contains the slide master</param>
        /// <returns>A SlideMasterPart with the resolved Id</returns>
        public static SlideMasterPart GetSlideMasterById(uint id, PresentationPart presentation)
        {
            string rid = null;

            foreach (SlideMasterId slideId in presentation.Presentation.SlideMasterIdList)
            {
                if (slideId.Id == id)
                {
                    rid = slideId.RelationshipId;
                    break;
                }
            }

            if (rid == null) return null;

            return (SlideMasterPart)presentation.GetPartById(rid);
        }
        #endregion
    }
}
